﻿using SD.Common;
using SD.Infrastructure.EntityBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SlamDunk.ValueObjects.Enums;
using SlamDunk.ValueObjects.Interfaces;

namespace SlamDunk.MES.Domain.Entities.PlanContxt
{
    /// <summary>
    /// 销售订单
    /// </summary>
    public class SaleOrder : AggregateRootEntity, ICheckable
    {
        #region # 构造器

        #region 00.无参构造器
        /// <summary>
        /// 无参构造器
        /// </summary>
        protected SaleOrder()
        {
            //初始化导航属性
            this.Details = new HashSet<SaleOrderDetail>();
        }
        #endregion

        #region 01.创建销售订单构造器
        /// <summary>
        /// 创建销售订单构造器
        /// </summary>
        /// <param name="orderNo">销售订单编号</param>
        /// <param name="orderName">销售订单名称</param>
        /// <param name="customerId">客户Id</param>
        /// <param name="issuedDate">下单日期</param>
        /// <param name="deliveryDate">交付日期</param>
        /// <param name="description">描述</param>
        public SaleOrder(string orderNo, string orderName, Guid customerId, DateTime issuedDate, DateTime deliveryDate, string description)
            : this()
        {
            base.Number = orderNo;
            base.Name = orderName;
            this.CustomerId = customerId;
            this.IssuedDate = issuedDate;
            this.DeliveryDate = deliveryDate;
            this.Description = description;

            //初始化关键字
            this.InitKeywords();
        }
        #endregion

        #endregion

        #region # 属性

        #region 客户Id —— Guid CustomerId
        /// <summary>
        /// 客户Id
        /// </summary>
        public Guid CustomerId { get; private set; }
        #endregion

        #region 下单日期 —— DateTime IssuedDate
        /// <summary>
        /// 下单日期
        /// </summary>
        public DateTime IssuedDate { get; private set; }
        #endregion

        #region 交付日期 —— DateTime DeliveryDate
        /// <summary>
        /// 交付日期
        /// </summary>
        public DateTime DeliveryDate { get; private set; }
        #endregion

        #region 提审人账号 —— string SubmitterAccount
        /// <summary>
        /// 提审人账号
        /// </summary>
        public string SubmitterAccount { get; set; }
        #endregion

        #region 提审人姓名 —— string SubmitterName
        /// <summary>
        /// 提审人姓名
        /// </summary>
        public string SubmitterName { get; set; }
        #endregion

        #region 审核状态 —— CheckStatus CheckStatus
        /// <summary>
        /// 审核状态
        /// </summary>
        public CheckStatus CheckStatus { get; set; }
        #endregion

        #region 审核意见 —— string CheckedRemark
        /// <summary>
        /// 审核意见
        /// </summary>
        public string CheckedRemark { get; set; }
        #endregion

        #region 审核人账号 —— string CheckerAccount
        /// <summary>
        /// 审核人账号
        /// </summary>
        public string CheckerAccount { get; set; }
        #endregion

        #region 审核人姓名 —— string CheckerName
        /// <summary>
        /// 审核人姓名
        /// </summary>
        public string CheckerName { get; set; }
        #endregion

        #region 审核时间 —— DateTime? CheckedTime
        /// <summary>
        /// 审核时间
        /// </summary>
        public DateTime? CheckedTime { get; set; }
        #endregion

        #region 描述 —— string Description
        /// <summary>
        /// 描述
        /// </summary>
        public string Description { get; private set; }
        #endregion

        #region 导航属性 - 销售订单明细集 —— ICollection<SaleOrderDetail> Details
        /// <summary>
        /// 导航属性 - 销售订单明细集
        /// </summary>
        public virtual ICollection<SaleOrderDetail> Details { get; private set; }
        #endregion

        #endregion

        #region # 方法

        #region 修改销售订单 —— void UpdateInfo(string orderName...
        /// <summary>
        /// 修改销售订单
        /// </summary>
        /// <param name="orderName">销售订单名称</param>
        /// <param name="customerId">客户Id</param>
        /// <param name="issuedDate">下单日期</param>
        /// <param name="deliveryDate">交付日期</param>
        /// <param name="description">描述</param>
        public void UpdateInfo(string orderName, Guid customerId, DateTime issuedDate, DateTime deliveryDate, string description)
        {
            #region # 验证

            if (this.CheckStatus == CheckStatus.Checking)
            {
                throw new InvalidOperationException("审核中的销售订单不可修改！");
            }
            if (this.CheckStatus == CheckStatus.Passed)
            {
                throw new InvalidOperationException("审核通过的销售订单不可修改！");
            }

            #endregion

            base.Name = orderName;
            this.CustomerId = customerId;
            this.IssuedDate = issuedDate;
            this.DeliveryDate = deliveryDate;
            this.Description = description;

            //初始化关键字
            this.InitKeywords();
        }
        #endregion

        #region 设置单据明细 —— void SetDetails(IEnumerable<SaleOrderDetail> details)
        /// <summary>
        /// 设置单据明细
        /// </summary>
        /// <param name="details">单据明细集</param>
        public void SetDetails(IEnumerable<SaleOrderDetail> details)
        {
            details = details?.ToArray() ?? new SaleOrderDetail[0];

            this.ClearDetails();
            if (details.Any())
            {
                this.Details.AddRange(details);
                foreach (SaleOrderDetail detail in details)
                {
                    detail.SaleOrder = this;
                }
            }
        }
        #endregion

        #region 提交审核 —— void Submit(string submitterAccount...
        /// <summary>
        /// 提交审核
        /// </summary>
        /// <param name="submitterAccount">提审人账号</param>
        /// <param name="submitterName">提审人姓名</param>
        public void Submit(string submitterAccount, string submitterName)
        {
            this.DoSubmit(submitterAccount, submitterName);
        }
        #endregion

        #region 审核 —— void Check(bool passed, string checkedRemark...
        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="passed">是否通过</param>
        /// <param name="checkedRemark">审核意见</param>
        /// <param name="checkedAccount">审核人账号</param>
        /// <param name="checkedName">审核人姓名</param>
        public void Check(bool passed, string checkedRemark, string checkedAccount, string checkedName)
        {
            this.DoCheck(passed, checkedRemark, checkedAccount, checkedName);
        }
        #endregion

        #region 清空单据明细 —— void ClearDetails()
        /// <summary>
        /// 清空单据明细
        /// </summary>
        private void ClearDetails()
        {
            foreach (SaleOrderDetail detail in this.Details.ToArray())
            {
                this.Details.Remove(detail);
            }
        }
        #endregion

        #region 初始化关键字 —— void InitKeywords()
        /// <summary>
        /// 初始化关键字
        /// </summary>
        private void InitKeywords()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append(base.Number);
            builder.Append(base.Name);
            builder.Append(this.Description);

            base.SetKeywords(builder.ToString());
        }
        #endregion

        #endregion
    }
}
